#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msvideo.h"
#include "ohos_video_h264_decoder.h"

static void ms_ohos_h264_dec_init(MSFilter *f) {
	OHOSVideoH264Decoder *d = new OHOSVideoH264Decoder(f);
	f->data = d;
}

static void ms_ohos_h264_dec_preprocess(MSFilter *f) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	d->initialize();
}

static void ms_ohos_h264_dec_process(MSFilter *f) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	d->feed();
}

static void ms_ohos_h264_dec_uninit(MSFilter *f) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	d->uninitialize();
	delete d;
}

static int msopenh264_dec_add_fmtp(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	const char *fmtp = static_cast<const char *>(arg);
	char value[256];
	if (fmtp_get_value(fmtp, "sprop-parameter-sets", value, sizeof(value))) {
		d->provideSpropParameterSets(value, sizeof(value));
	}
	return 0;
}

static int msopenh264_dec_reset_first_image(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	d->resetFirstImageDecoded();
	return 0;
}

static int msopenh264_dec_enable_avpf(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	d->enableAVPF(*((bool_t *)arg) ? true : false);
	return 0;
}

static int msopenh264_dec_get_size(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	MSVideoSize *size = static_cast<MSVideoSize *>(arg);
	*size = d->getSize();
	return 0;
}

static int msopenh264_dec_get_fps(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	*(float *)arg = d->getFps();
	return 0;
}

static int msopenh264_dec_get_out_fmt(MSFilter *f, void *arg) {
	OHOSVideoH264Decoder *d = static_cast<OHOSVideoH264Decoder *>(f->data);
	((MSPinFormat *)arg)->pin = 0;
	((MSPinFormat *)arg)->fmt = d->getOutFmt();
	return 0;
}

static MSFilterMethod ms_ohos_h264_dec_methods[] = {
    {MS_FILTER_ADD_FMTP, msopenh264_dec_add_fmtp},
    {MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION, msopenh264_dec_reset_first_image},
    {MS_VIDEO_DECODER_ENABLE_AVPF, msopenh264_dec_enable_avpf},
    {MS_FILTER_GET_VIDEO_SIZE, msopenh264_dec_get_size},
    {MS_FILTER_GET_FPS, msopenh264_dec_get_fps},
    {MS_FILTER_GET_OUTPUT_FMT, msopenh264_dec_get_out_fmt},
    {0, NULL}};

MSFilterDesc ms_ohos_video_dec_desc = {MS_OHOS_VIDEO_DEC,
                                       "OHOSVideoDecoder",
                                       "OHOS video h264 decoder",
                                       MS_FILTER_DECODER,
                                       "H264",
                                       1,
                                       1,
                                       ms_ohos_h264_dec_init,
                                       ms_ohos_h264_dec_preprocess,
                                       ms_ohos_h264_dec_process,
                                       NULL,
                                       ms_ohos_h264_dec_uninit,
                                       ms_ohos_h264_dec_methods,
                                       0};

MS_FILTER_DESC_EXPORT(ms_ohos_video_dec_desc)